home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / jget.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-15  |  19.9 KB  |  796 lines

  1. /* 
  2.  * jget.c --
  3.  *
  4.  *    Perform ls on Jaquith archive system.
  5.  *
  6.  * Copyright 1991 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Quote:
  16.  *       "The limits of my language mean the limits of my world."
  17.  *        -- Ludwig Wittgenstein
  18.  *
  19.  */
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/jget.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  23. #endif /* not lint */
  24.  
  25. #include "jaquith.h"
  26. #include "option.h"
  27. #include "jgetInt.h"
  28.  
  29. #define STDOUT 1
  30.  
  31. int syserr;
  32. int jDebug;
  33.  
  34. static void  CheckOptions  _ARGS_ ((Parms *parmsPtr));
  35. static void  SendStrings   _ARGS_ ((int argc, char **argv, int sock));
  36. static void  ReadAndCopyData _ARGS_ ((int sock, Parms *parmsPtr,
  37.                        char *relName));
  38. static void  ReadAndMakeFiles _ARGS_ ((int sock, Parms *parmsPtr,
  39.                        char *relName));
  40. static int   OpenCreate    _ARGS_ ((T_FileStat *statInfoPtr, int clobber,
  41.                     int *fileStreamPtr));
  42. static int   OpenObject    _ARGS_ ((T_FileStat *statInfoPtr));
  43. static int   RestoreAttrs  _ARGS_ ((T_FileStat *statInfoPtr));
  44. static void  RestoreDirAttrs  _ARGS_ ((Q_Handle *dirQ));
  45. static int   IsWriteable   _ARGS_ ((T_FileStat *statInfoPtr));
  46.  
  47. static char printBuf[T_MAXSTRINGLEN];
  48. static FILE *memDbg = NULL;
  49.  
  50. static int myUid;
  51. static char *myName;
  52. static int myGid;
  53. static char *myGroup;
  54. static int rootUid;
  55.  
  56. Parms parms = {
  57.     "",
  58.     -1,
  59.     "",
  60.     DEF_RANGE,
  61.     DEF_ASOF,
  62.     DEF_SINCE,
  63.     DEF_ABS,
  64.     DEF_OWNER,
  65.     DEF_GROUP,
  66.     DEF_MAIL,
  67.     DEF_RECURSE,
  68.     DEF_MODDATE,
  69.     DEF_ALL,
  70.     DEF_FIRSTVER,
  71.     DEF_LASTVER,
  72.     DEF_FIRSTDATE,
  73.     DEF_LASTDATE,
  74.     DEF_CLOBBER,
  75.     DEF_VERBOSE,
  76.     DEF_TARGET,
  77.     DEF_FILTER,
  78.     DEF_TAR,
  79.     T_TARSIZE
  80. };
  81.  
  82. Option optionArray[] = {
  83.     {OPT_STRING, "server", (char *)&parms.server, "Server host"},
  84.     {OPT_INT, "port", (char *)&parms.port, "Port of server"},
  85.     {OPT_STRING, "arch", (char *)&parms.arch, "Logical archive name"},
  86.     {OPT_STRING, "range", (char *)&parms.range, "Date range"},
  87.     {OPT_STRING, "asof", (char *)&parms.asof, "Date specification"},
  88.     {OPT_STRING, "since", (char *)&parms.since, "Date specification"},
  89.     {OPT_STRING, "abs", (char *)&parms.abs, "Abstract regular expression"},
  90.     {OPT_STRING, "owner", (char *)&parms.owner, "Userid of owner"},
  91.     {OPT_STRING, "group", (char *)&parms.group, "Group name"},
  92.     {OPT_STRING, "mail", (char *)&parms.mail, "Mail address"},
  93.     {OPT_TRUE, "moddate", (char *)&parms.modDate, "Use last-modification date, not archive date"},
  94.     {OPT_INT, "first", (char *)&parms.firstVer, "Item number. See man page."},
  95.     {OPT_INT, "last", (char *)&parms.lastVer, "Item number. See man page."},
  96.     {OPT_TRUE, "all", (char *)&parms.all, "Synonym for -first 1 -last -1"},
  97.     {OPT_STRING, "target", (char *)&parms.target, "Restore file hierarchy relative to specified directory"},
  98.     {OPT_TRUE, "clobber", (char *)&parms.clobber, "Overwrite existing file."},
  99.     {OPT_TRUE, "v", (char *)&parms.verbose, "Verbose mode."},
  100.     {OPT_TRUE, "dir", (char *)&parms.recurse, "Restore directory and top-level contents only"},
  101.     {OPT_TRUE, "filter", (char *)&parms.filter, "Restore raw data to stdout."},
  102.     {OPT_TRUE, "tar", (char *)&parms.tar, "Restore data to stdout in tar format."},
  103.     {OPT_INT, "tarbuf", (char *)&parms.tarBuf, "Buffer size of -tar option."}
  104. };
  105. int numOptions = sizeof(optionArray) / sizeof(Option);
  106.  
  107.  
  108. /*
  109.  *----------------------------------------------------------------------
  110.  *
  111.  * main --
  112.  *
  113.  *    Main driver for als program.
  114.  *
  115.  * Results:
  116.  *    none.
  117.  *
  118.  * Side effects:
  119.  *    Sends requests across socket to tapestry server.
  120.  *
  121.  *----------------------------------------------------------------------
  122.  */
  123.  
  124. int
  125. main(argc, argv)
  126. int argc;
  127. char *argv[];
  128. {
  129.     int sock;
  130.     T_RespMsgHdr resp;
  131.     char defaultName = '\0';
  132.     char *defaultList = &defaultName;
  133.     int nameCnt = 1;
  134.     char **nameList = &defaultList;
  135.     int i;
  136.  
  137. /*    memDbg = fopen("jls.mem", "w"); */
  138.     MEM_CONTROL(8192, memDbg, TRACEMEM+TRACECALLS, 4096);
  139.  
  140.     argc = Opt_Parse(argc, argv, optionArray, numOptions, 0);
  141.  
  142.     CheckOptions(&parms);
  143.  
  144.     myUid = geteuid();
  145.     myName = Utils_GetLoginByUid(myUid);
  146.     myGid = getegid();
  147.     myGroup = Utils_GetGroupByGid(myGid);
  148.     rootUid = Utils_GetUidByLogin(ROOT_LOGIN);
  149.  
  150.     sock = Sock_SetupSocket(parms.port, parms.server, 1);
  151.  
  152.     Sock_SendReqHdr(sock, T_CMDGET, 0, parms.mail, parms.arch, 0);
  153.  
  154.     /* put out query parameters */
  155.     Sock_WriteInteger(sock, parms.firstVer);
  156.     Sock_WriteInteger(sock, parms.lastVer);
  157.     Sock_WriteInteger(sock, parms.firstDate);
  158.     Sock_WriteInteger(sock, parms.lastDate);
  159.     Sock_WriteString(sock, parms.owner, 0);
  160.     Sock_WriteString(sock, parms.group, 0);
  161.     Sock_WriteInteger(sock, parms.modDate);
  162.     Sock_WriteInteger(sock, parms.recurse);
  163.     Sock_WriteString(sock, parms.abs, 0);
  164.  
  165.     /* get ok to continue */
  166.     Sock_ReadRespHdr(sock, &resp);
  167.     if (resp.status != T_SUCCESS) {
  168.     fprintf(stdout,"%s", Utils_MakeErrorMsg(resp.status, resp.errno));
  169.     close(sock);
  170.     exit(-1);
  171.     }
  172.  
  173.     if (argc > 1) {
  174.     nameCnt = argc - 1;
  175.     nameList = &argv[1];
  176.     }
  177.  
  178.     for (i=0; i<nameCnt; i++) {
  179.     nameList[i] = Utils_MakeFullPath(nameList[i]);
  180.     Sock_WriteInteger(sock, 1);
  181.     Sock_WriteString(sock, nameList[i], 0);
  182.     if ((parms.filter) || (parms.tar)) {
  183.         ReadAndCopyData(sock, &parms, nameList[i]);
  184.     } else {
  185.         ReadAndMakeFiles(sock, &parms, nameList[i]);
  186.     }
  187.     }
  188.  
  189.     Sock_ReadRespHdr(sock, &resp);
  190.     if (resp.status != T_SUCCESS) {
  191.     fprintf(stdout,"%s", Utils_MakeErrorMsg(resp.status, resp.errno));
  192.     }
  193.  
  194.     close(sock);
  195.     MEM_REPORT("jget", ALLROUTINES, SORTBYREQ);
  196.  
  197.     return(0);
  198.  
  199. }
  200.  
  201.  
  202.  
  203. /*
  204.  *----------------------------------------------------------------------
  205.  *
  206.  * ReadAndCopyData --
  207.  *
  208.  *    Retrieve data for one query and spew it to stdout
  209.  *
  210.  * Results:
  211.  *    none.
  212.  *
  213.  * Side effects:
  214.  *    none.
  215.  *
  216.  *----------------------------------------------------------------------
  217.  */
  218.  
  219. static void
  220. ReadAndCopyData(sock, parmsPtr, pathName)
  221.     int sock;                 /* incoming socket */
  222.     Parms *parmsPtr;          /* globals */
  223.     char *pathName;           /* user-specified pathname */
  224. {
  225.     int retCode;
  226.     char *buf;
  227.     T_FileStat statInfo;
  228.     int totalSize = 0;
  229.     int fileSize;
  230.     int size;
  231.     int cnt;
  232.     char *oldFileName;
  233.     int pathLen;
  234.  
  235.     Str_StripDots(pathName);
  236.     pathLen = STRRCHR(pathName, '/') - pathName;
  237.     
  238.     buf = (char *)MEM_ALLOC("ReadAndCopyData", parmsPtr->tarBuf*sizeof(char));
  239.  
  240.     while ((retCode=Sock_ReadFileStat(sock, &statInfo, 1))
  241.        == T_SUCCESS) {
  242.     if (!*statInfo.fileName) {
  243.         if ((parmsPtr->tar) && (totalSize > 0)) {
  244.         TBuf_Terminate(STDOUT, totalSize);
  245.         }
  246.         MEM_FREE("ReadAndCopyData", buf);
  247.         return;
  248.     }
  249.     if (*parmsPtr->target) {
  250.         oldFileName = statInfo.fileName;
  251.         statInfo.fileName = Str_Cat(2, parmsPtr->target, 
  252.                     oldFileName+pathLen);
  253.         MEM_FREE("ReadAndCopyData", oldFileName);
  254.     }
  255.     size = statInfo.size;
  256.     if (parmsPtr->tar) {
  257.         fileSize = TBuf_WriteTarHdr(STDOUT, &statInfo) + size;
  258.         totalSize += fileSize;
  259.     }
  260.     while (size > 0) {
  261.         cnt = (size > parmsPtr->tarBuf) ? parmsPtr->tarBuf : size;
  262.         if ((cnt=read(sock, buf, cnt)) < 0) {
  263.         retCode = T_IOFAILED;
  264.         sprintf(printBuf, "Reading %s", statInfo.fileName);
  265.         perror(printBuf);
  266.         break;
  267.         }
  268.         size -= cnt;
  269.         if (parmsPtr->tar) {
  270.         cnt = parmsPtr->tarBuf;
  271.         }
  272.         if ((retCode == T_SUCCESS) &&
  273.         (write(STDOUT, buf, cnt) != cnt)) {
  274.         retCode = T_IOFAILED;
  275.         sprintf(printBuf, "Writing %s", statInfo.fileName);
  276.         perror(printBuf);
  277.         }
  278.     }
  279.     if (retCode == T_SUCCESS) {
  280.         if (parmsPtr->verbose) {
  281.         fprintf(stderr,"%s\n", statInfo.fileName);
  282.         }
  283.         if (parmsPtr->tar) {
  284.         totalSize += TBuf_Pad(STDOUT, fileSize, T_TBLOCK);
  285.         }
  286.         Utils_FreeFileStat(&statInfo, 0);
  287.     }
  288.     }
  289.     MEM_FREE("ReadAndCopyData", buf);
  290.     printf("Got error trying to read T_FileStat\n");
  291.  
  292. }
  293.  
  294.  
  295. /*
  296.  *----------------------------------------------------------------------
  297.  *
  298.  * ReadAndMakeFiles --
  299.  *
  300.  *    Retrieve and build all the files for one query
  301.  *
  302.  * Results:
  303.  *    none.
  304.  *
  305.  * Side effects:
  306.  *    none.
  307.  *
  308.  *----------------------------------------------------------------------
  309.  */
  310.  
  311. static void
  312. ReadAndMakeFiles(sock, parmsPtr, pathName)
  313.     int sock;                 /* incoming socket */
  314.     Parms *parmsPtr;          /* globals */
  315.     char *pathName;           /* user-specified pathname */
  316. {
  317.     int fileStream;
  318.     int retCode;
  319.     char buf[T_BUFSIZE];
  320.     T_FileStat statInfo;
  321.     int size;
  322.     int cnt;
  323.     char *oldFileName;
  324.     int pathLen;
  325.     Q_Handle *dirQ;
  326.     T_FileStat *newInfoPtr;
  327.  
  328.     dirQ = Q_Create("dirList", 0);
  329.  
  330.     Str_StripDots(pathName);
  331.     pathLen = STRRCHR(pathName, '/') - pathName;
  332.     
  333.     while ((retCode=Sock_ReadFileStat(sock, &statInfo, 1))
  334.        == T_SUCCESS) {
  335.     if (!*statInfo.fileName) {
  336.         RestoreDirAttrs(dirQ);
  337.         Q_Destroy(dirQ);
  338.         return;
  339.     }
  340.     if (*parmsPtr->target) {
  341.         oldFileName = statInfo.fileName;
  342.         statInfo.fileName = Str_Cat(2, parmsPtr->target, 
  343.                     oldFileName+pathLen);
  344.         MEM_FREE("ReadAndMakeFiles", oldFileName);
  345.     }
  346.     if ((retCode=OpenCreate(&statInfo, parmsPtr->clobber, &fileStream))
  347.         != T_SUCCESS) {
  348.         perror(statInfo.fileName);
  349.     }
  350.     size = statInfo.size;
  351.     while (size > 0) {
  352.         cnt = (size > sizeof(buf)) ? sizeof(buf) : size;
  353.         if ((cnt=read(sock, buf, cnt)) < 0) {
  354.         retCode = T_IOFAILED;
  355.         sprintf(printBuf, "Reading %s", statInfo.fileName);
  356.         perror(printBuf);
  357.         break;
  358.         }
  359.         if ((retCode == T_SUCCESS) &&
  360.         (write(fileStream, buf, cnt) != cnt)) {
  361.         retCode = T_IOFAILED;
  362.         sprintf(printBuf, "Writing %s", statInfo.fileName);
  363.         perror(printBuf);
  364.         }
  365.         size -= cnt;
  366.     }
  367.     if ((retCode == T_SUCCESS) && (parmsPtr->verbose)) {
  368.         fprintf(stdout,"%s\n", statInfo.fileName);
  369.     }
  370.     if (retCode == T_SUCCESS) {
  371.         /*
  372.          * If it's a directory and it's not writeable, save its permissions
  373.          * so we can restore them after we've created all its children.
  374.          */
  375.         if (S_ISDIR(statInfo.mode) &&
  376.         (!IsWriteable(&statInfo))) {
  377.         newInfoPtr = Utils_CopyFileStat(&statInfo);
  378.         Q_Add(dirQ, (Q_ClientData) newInfoPtr, Q_TAILQ);
  379.         } else {
  380.         RestoreAttrs(&statInfo);
  381.         }
  382.         Utils_FreeFileStat(&statInfo, 0);
  383.     }
  384.     if (fileStream > 0) {
  385.         close(fileStream);
  386.     }
  387.     }
  388.     printf("Got error trying to read T_FileStat\n");
  389.  
  390. }
  391.  
  392.  
  393. /*
  394.  *----------------------------------------------------------------------
  395.  *
  396.  * RestoreDirAttrs --
  397.  *
  398.  *    Run through list of protected directories restoring their attrs.
  399.  *
  400.  * Results:
  401.  *    none.
  402.  *
  403.  * Side effects:
  404.  *    Frees directory items after they're restored.
  405.  *
  406.  *----------------------------------------------------------------------
  407.  */
  408.  
  409. static void
  410. RestoreDirAttrs(dirQ)
  411.     Q_Handle *dirQ;           /* source item to be restored */
  412. {
  413.     int count;
  414.     T_FileStat *statInfoPtr;
  415.  
  416.     count = Q_Count(dirQ);
  417.     while (count-- > 0) {
  418.     statInfoPtr = (T_FileStat *)Q_Remove(dirQ);
  419.     RestoreAttrs(statInfoPtr);
  420.     Utils_FreeFileStat(statInfoPtr, 1);
  421.     }
  422. }
  423.  
  424.  
  425. /*
  426.  *----------------------------------------------------------------------
  427.  *
  428.  * RestoreAttrs --
  429.  *
  430.  *    Recreate file's attributes
  431.  *
  432.  * Results:
  433.  *    none.
  434.  *
  435.  * Side effects:
  436.  *    none.
  437.  *
  438.  *----------------------------------------------------------------------
  439.  */
  440.  
  441. static int
  442. RestoreAttrs(statInfoPtr)
  443.     T_FileStat *statInfoPtr;
  444. {
  445.     int retCode = T_SUCCESS;
  446. #ifdef SYSV
  447.     struct utimbuf fileTimes;
  448. #else
  449.     struct timeval fileTimes[2];
  450. #endif
  451.  
  452.     if (!S_ISALNK(statInfoPtr->mode)) {
  453. #ifdef SYSV
  454.     fileTimes.actime = statInfoPtr->atime;
  455.     fileTimes.modtime = statInfoPtr->mtime;
  456.         if (utime(statInfoPtr->fileName, &fileTimes) < 0) {
  457. #else
  458.         fileTimes[0].tv_sec = statInfoPtr->atime;
  459.     fileTimes[0].tv_usec = 0;
  460.         fileTimes[1].tv_sec = statInfoPtr->mtime;
  461.     fileTimes[1].tv_usec = 0;
  462.         if (utimes(statInfoPtr->fileName, fileTimes) < 0) {
  463. #endif
  464.         sprintf(printBuf, "Restoring access times %s",
  465.             statInfoPtr->fileName);
  466.         perror(printBuf);
  467.     }
  468.     if (chmod(statInfoPtr->fileName, statInfoPtr->mode) < 0) {
  469.         sprintf(printBuf, "Restoring permissions %s",
  470.             statInfoPtr->fileName);
  471.         perror(printBuf);
  472.     }
  473.     }
  474.  
  475.     if (chown(statInfoPtr->fileName, 
  476.           (uid_t)statInfoPtr->uid, (gid_t)statInfoPtr->gid) < 0) {
  477.     sprintf(printBuf, "Restoring owner/group %s",
  478.         statInfoPtr->fileName);
  479.     perror(printBuf);
  480.     }
  481.  
  482.  
  483.     return retCode;
  484. }
  485.  
  486.  
  487.  
  488. /*
  489.  *----------------------------------------------------------------------
  490.  *
  491.  * OpenCreate --
  492.  *
  493.  *    Open file, creating directories as needed.
  494.  *
  495.  * Results:
  496.  *    none.
  497.  *
  498.  * Side effects:
  499.  *    none.
  500.  *
  501.  *----------------------------------------------------------------------
  502.  */
  503.  
  504. static int
  505. OpenCreate(statInfoPtr, clobber, fileStreamPtr)
  506.     T_FileStat *statInfoPtr;
  507.     int clobber;
  508.     int *fileStreamPtr;
  509. {
  510.     char *curPtr;
  511.     char *safeName;
  512.  
  513.     if (clobber) {
  514.     if (S_ISDIR(statInfoPtr->mode)) {
  515.         safeName = Str_Quote(statInfoPtr->fileName);
  516.         sprintf(printBuf, "rm -rf %s", safeName);
  517.         system(printBuf);
  518.         MEM_FREE("OpenCreate",safeName);
  519.     } else {
  520.         unlink(statInfoPtr->fileName);
  521.     }
  522.     }
  523.  
  524.     *fileStreamPtr = OpenObject(statInfoPtr);
  525.  
  526.     if (*fileStreamPtr > -1) {
  527.     return T_SUCCESS;
  528.     } else if (errno != ENOENT) {
  529.     return T_FAILURE;
  530.     }
  531.     
  532.     /*
  533.      * some part of the path is not there
  534.      */
  535.     curPtr = statInfoPtr->fileName;
  536.     
  537.     while (curPtr != NULL) {
  538.     if ((curPtr=STRCHR(curPtr+1, '/')) == NULL) {
  539.         return T_FAILURE;
  540.     }
  541.     *curPtr = '\0';
  542.     if (access(statInfoPtr->fileName, X_OK) == -1) {
  543.         break;
  544.     }
  545.     *curPtr = '/';
  546.     } 
  547.  
  548.     while (curPtr != NULL) {
  549.     *curPtr = '\0';
  550.     if (mkdir(statInfoPtr->fileName, 0700) == -1) {
  551.         return T_FAILURE;
  552.     }
  553.     *curPtr = '/';
  554.     curPtr = STRCHR(curPtr+1, '/');
  555.     } 
  556.  
  557.     /*
  558.      * Now retry the open
  559.      */
  560.     *fileStreamPtr = OpenObject(statInfoPtr);
  561.  
  562.     return (*fileStreamPtr == -1) ? T_FAILURE : T_SUCCESS;
  563.  
  564. }
  565.  
  566.  
  567. /*
  568.  *----------------------------------------------------------------------
  569.  *
  570.  * OpenObject --
  571.  *
  572.  *    Do the right thing to create the object.
  573.  *
  574.  * Results:
  575.  *    Open stream or resulting return code.
  576.  *
  577.  * Side effects:
  578.  *    Opens file, makes directory, link or device.
  579.  *
  580.  *----------------------------------------------------------------------
  581.  */
  582.  
  583. static int
  584. OpenObject(statInfoPtr)
  585.     T_FileStat *statInfoPtr;
  586. {
  587.     int result = T_SUCCESS;
  588.     int mode = statInfoPtr->mode & S_IFMT;
  589.     char *fileName = statInfoPtr->fileName;
  590.     int perm = statInfoPtr->mode & 0777;
  591.  
  592.     switch (mode) {
  593.     case S_IFDIR:
  594.     mkdir(fileName, 0700); /* we'll change the permission later */
  595.     break;
  596.     case S_IFLNK:
  597.     result = symlink(statInfoPtr->linkName, fileName);
  598.     break;
  599.     case S_IFBLK:
  600.     case S_IFCHR:
  601.     result = mknod(fileName, perm, statInfoPtr->rdev);
  602.     break;
  603.     case S_IFIFO:
  604.     result = mknod(fileName, S_IFIFO+perm, statInfoPtr->rdev);
  605.     break;
  606.     case S_IFRLNK:
  607.     result = MAKERMTLINK(statInfoPtr->linkName, fileName, 1);
  608.     break;
  609.     default:
  610.     result = open(statInfoPtr->fileName,
  611.               O_WRONLY+O_CREAT+O_EXCL, perm);
  612.     break;
  613.     }
  614.  
  615.     return result;
  616. }
  617.  
  618.  
  619.  
  620. /*
  621.  *----------------------------------------------------------------------
  622.  *
  623.  * CheckOptions -- 
  624.  *
  625.  *    Make sure command line options look reasonable
  626.  *
  627.  * Results:
  628.  *    none.
  629.  *
  630.  * Side effects:
  631.  *    none.
  632.  *
  633.  *----------------------------------------------------------------------
  634.  */
  635.  
  636. static void
  637. CheckOptions(parmsPtr)
  638.     Parms *parmsPtr;          /* command line args */
  639. {
  640.     struct timeb timeB1;
  641.     struct timeb timeB2;
  642.     char *envPtr;
  643.     int targetLen;
  644.     struct stat unixStatBuf;
  645.  
  646.     if ((!*parmsPtr->arch) &&
  647.     ((envPtr=getenv(ENV_ARCHIVE_VAR)) != (char *)NULL)) {
  648.     parmsPtr->arch = envPtr;
  649.     }
  650.     if ((*parmsPtr->arch) &&
  651.     (Utils_CheckName(parmsPtr->arch, 1) == T_FAILURE)) {
  652.     sprintf(printBuf,
  653.         "Bad archive name: '%s'.\nUse -arch or set %s environment variable.\n",
  654.         parmsPtr->arch, ENV_ARCHIVE_VAR);
  655.     Utils_Bailout(printBuf, BAIL_PRINT);
  656.     }
  657.     if ((!*parmsPtr->server) &&
  658.     ((parmsPtr->server=getenv(ENV_SERVER_VAR)) == (char *)NULL)) {
  659.     parmsPtr->server = DEF_SERVER;
  660.     }
  661.     if (Utils_CheckName(parmsPtr->server, 1) == T_FAILURE) {
  662.     sprintf(printBuf,
  663.         "Bad server name: '%s'.\nUse -server or set %s environment variable.\n",
  664.         parmsPtr->server, ENV_SERVER_VAR);
  665.     Utils_Bailout(printBuf, BAIL_PRINT);
  666.     }
  667.     if (parmsPtr->port == -1) {
  668.     if ((envPtr=getenv(ENV_PORT_VAR)) == (char *)NULL) {
  669.         parmsPtr->port = DEF_PORT;
  670.     } else {
  671.         Utils_CvtInteger(envPtr, 1, SHRT_MAX, &parmsPtr->port);
  672.     }
  673.     }
  674.     if ((parmsPtr->port < 1) || (parmsPtr->port > SHRT_MAX)) {
  675.     sprintf(printBuf,
  676.         "Bad port number %d.\nUse -port or set %s environment variable\n",
  677.         parmsPtr->port, ENV_PORT_VAR);
  678.     Utils_Bailout(printBuf, BAIL_PRINT);
  679.     }
  680.     if ((*parmsPtr->mail) && 
  681.     (Utils_CheckName(parmsPtr->mail, 1) != T_SUCCESS)) {
  682.     sprintf(printBuf, "Bad mail address: '%s'\n", parmsPtr->mail);
  683.     Utils_Bailout(printBuf, BAIL_PRINT);
  684.     }
  685.     if ((strcmp(parmsPtr->owner, DEF_OWNER) != 0) &&
  686.     (Utils_GetUidByLogin(parmsPtr->owner) == T_FAILURE)) {
  687.     sprintf(printBuf, "Don't know user '%s'. Continue? [y/n] ",
  688.         parmsPtr->owner);
  689.         if (!Utils_GetOk(printBuf)) {
  690.         exit(-1);
  691.     }
  692.     }
  693.     if ((strcmp(parmsPtr->group, DEF_GROUP) != 0) &&
  694.     (Utils_GetGidByGroup(parmsPtr->group) == T_FAILURE)) {
  695.     sprintf(printBuf, "Don't know group '%s'. Continue? [y/n] ",
  696.         parmsPtr->group);
  697.         if (!Utils_GetOk(printBuf)) {
  698.         exit(-1);
  699.     }
  700.     }
  701.     if ((*parmsPtr->asof) && (*parmsPtr->since)) {
  702.     Utils_Bailout("Conflicting parameters: -asof -since\n", BAIL_PRINT);
  703.     }
  704.     if (*parmsPtr->asof) {
  705.     if (getindate(parmsPtr->asof, &timeB1) != T_SUCCESS) {
  706.         Utils_Bailout("Need date in format: 20-Mar-1980:10:20:0",
  707.               BAIL_PRINT);
  708.     }
  709.     parmsPtr->firstDate = 0;
  710.     parmsPtr->lastDate = timeB1.time;
  711.     }
  712.     if (*parmsPtr->since) {
  713.     if (getindate(parmsPtr->asof, &timeB1) != T_SUCCESS) {
  714.         Utils_Bailout("Need date in format: 20-Mar-1980:10:20:0",
  715.               BAIL_PRINT);
  716.     }
  717.     parmsPtr->firstDate = timeB1.time;
  718.     parmsPtr->lastDate = Time_GetCurDate();
  719.     }
  720.     if (*parmsPtr->range) {
  721.     if (getindatepair(parmsPtr->range, &timeB1, &timeB2) !=
  722.         T_SUCCESS) {
  723.         Utils_Bailout("Need date pair in format: date,date2", BAIL_PRINT);
  724.     }
  725.     parmsPtr->firstDate = timeB1.time;
  726.     parmsPtr->lastDate  = timeB2.time;
  727.     }
  728.     if (parmsPtr->all) {
  729.     if ((parms.firstVer != DEF_FIRSTVER) ||
  730.         (parms.lastVer != DEF_LASTVER)) {
  731.         Utils_Bailout("Don't mix -all option with -first or -last",
  732.             BAIL_PRINT);
  733.     } else {
  734.         parms.firstVer = 1;
  735.         parms.lastVer = -1;
  736.     }
  737.     }
  738.     if ((parms.firstVer == 0) || (parms.lastVer == 0)) {
  739.     Utils_Bailout("Version number cannot be 0.\n", BAIL_PRINT);
  740.     }
  741.     if (*parmsPtr->target) {
  742.     if (stat(parmsPtr->target, &unixStatBuf) != 0) {
  743.         Utils_Bailout("Couldn't read or access target directory\n",
  744.               BAIL_PRINT);
  745.     }
  746.     if (!S_ISADIR(unixStatBuf.st_mode)) {
  747.         Utils_Bailout("Specified target isn't a directory.\n", BAIL_PRINT);
  748.     }
  749.     }
  750.     targetLen = strlen(parmsPtr->target) - 1;
  751.     if (*(parmsPtr->target+targetLen) == '/') {
  752.     *(parmsPtr->target+targetLen) = '\0';
  753.     }
  754.     if ((parmsPtr->tarBuf < 0) ||
  755.     (parmsPtr->tarBuf % T_TBLOCK)) {
  756.     sprintf(printBuf, "tarbuf argument must be > 0 and a multiple of %d.\n",
  757.         T_TBLOCK);
  758.     Utils_Bailout(printBuf, BAIL_PRINT);
  759.     }
  760. }
  761.  
  762. /*
  763.  *----------------------------------------------------------------------
  764.  *
  765.  * IsWriteable --
  766.  *
  767.  *    Check for proper write permission.
  768.  *
  769.  * Results:
  770.  *    1 == writable; 0 = protected.
  771.  *
  772.  * Side effects:
  773.  *    None.
  774.  *
  775.  * Note:
  776.  *      Uses global uid, gid variables
  777.  *
  778.  *----------------------------------------------------------------------
  779.  */
  780.  
  781. static int
  782. IsWriteable(unixStatPtr)
  783.     struct stat *unixStatPtr; /* file in question */
  784. {
  785.     int perm = unixStatPtr->st_mode & 0777;
  786.  
  787.     if ((myUid == rootUid) ||
  788.     (perm & 02) ||
  789.     ((perm & 020) && (myGid == unixStatPtr->st_gid)) ||
  790.     ((perm & 0200) && (myUid == unixStatPtr->st_uid))) {
  791.     return 1;
  792.     }
  793.  
  794.     return 0;
  795. }
  796.